﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Collections.Specialized;

namespace Inline.SharePoint.ExtendedVariations.Helpers
{

    class ItemHandler
    {

        /// <summary>
        /// Add item from the source list to the target list
        /// </summary>
        /// <param name="targetList">The target list to copy item to</param>
        /// <param name="item">Item to add to target list/param>
        public void AddItem(StringCollection variationUrls, SPItemEventProperties properties)
        {

            for (int i = 0; i < variationUrls.Count; i++)
            {
                
                using (SPSite site = new SPSite(variationUrls[i]))
                {

                    using (SPWeb web = site.OpenWeb())
                    {

                        SPList targetList = web.Lists.TryGetList(properties.ListTitle);

                        if (targetList == null) // Create the list if not already there on the target
                        {

                            Guid listId = web.Lists.Add(properties.ListTitle, properties.List.Description, properties.List.BaseTemplate);
                            targetList = web.Lists[listId];

                        }

                        // If the item is not a document, we use the title as a key. Else the filename.
                        string key = string.Empty, keyColumn = string.Empty, type = string.Empty;
                        if (properties.ListItem.File == null)
                        {

                            keyColumn = "Title";
                            type = "Text";
                            key = properties.ListItem.Title;

                        }
                        else
                        {

                            keyColumn = "FileLeafRef";
                            type = "File";
                            key = properties.ListItem.File.Name;

                        }

                        SPListItem item = GetListItemViaCamlQuery(targetList, keyColumn, type, key);;

                        if (item == null) // Item does not yet exist so create new one
                        {

                            if (properties.ListItem.File == null)
                            {

                                item = targetList.Items.Add();

                            }
                            else
                            {

                                item = targetList.RootFolder.Files.Add(properties.ListItem.File.Url, properties.ListItem.File.OpenBinary(), true).Item;

                            }

                        }
                        else // Item does exist so overwrite file correctly if available
                        {

                            if (properties.ListItem.File != null)
                            {

                                if (targetList.ForceCheckout)
                                {

                                    if (item.File.CheckOutType == SPFile.SPCheckOutType.None)
                                        item.File.CheckOut();

                                    item = targetList.RootFolder.Files.Add(properties.ListItem.File.Url, properties.ListItem.File.OpenBinary(), true).Item;

                                }

                            }

                        }

                        SPFieldCollection fColl = properties.ListItem.Fields;
                        for (int j = 0; j < fColl.Count; j++)
                        {

                            SPField field = item.Fields.GetFieldByInternalName(fColl[j].StaticName);

                            if(!field.ReadOnlyField)
                                item[fColl[j].StaticName] = properties.ListItem[fColl[j].StaticName];

                        }

                        targetList.ParentWeb.AllowUnsafeUpdates = true;
                        item.Update();
                        if (targetList.ForceCheckout)
                        {

                            if (item.File.CheckOutType != SPFile.SPCheckOutType.None)
                                item.File.CheckIn("Inline.ExtendedVariations");

                        }
                        targetList.ParentWeb.AllowUnsafeUpdates = false;

                    }

                }

            }

        }

        /// <summary>
        /// Update an existing item in the variations
        /// </summary>
        /// <param name="variationUrls"></param>
        /// <param name="properties"></param>
        public void UpdateItem(StringCollection variationUrls, SPItemEventProperties properties)
        {

            for (int i = 0; i < variationUrls.Count; i++)
            {

                using (SPSite site = new SPSite(variationUrls[i]))
                {

                    using (SPWeb web = site.OpenWeb())
                    {

                        SPList targetList = web.Lists.TryGetList(properties.ListTitle);

                        if (targetList == null) // Create the list if not already there on the target
                        {

                            Guid listId = web.Lists.Add(properties.ListTitle, properties.List.Description, properties.List.BaseTemplate);
                            targetList = web.Lists[listId];

                        }

                        // If the item is not a document, we use the title as a key. Else the filename.
                        string key = string.Empty, keyColumn = string.Empty, type = string.Empty;
                        if (properties.ListItem.File == null)
                        {

                            keyColumn = "Title";
                            type = "Text";
                            key = properties.ListItem.Title;

                        }
                        else
                        {

                            keyColumn = "FileLeafRef";
                            type = "File";
                            key = properties.ListItem.File.Name;

                        }

                        // Find item based on key
                        SPListItem item = GetListItemViaCamlQuery(targetList, keyColumn, type, key);

                        if(item != null) // Can max be one or else we don't know which one to update
                        {

                            if (item.File != null)
                            {

                                if (targetList.ForceCheckout && item.File.CheckOutType == SPFile.SPCheckOutType.None)
                                    item.File.CheckOut();

                            }

                            SPFieldCollection fColl = properties.ListItem.Fields;
                            for (int j = 0; j < fColl.Count; j++)
                            {

                                SPField field = item.Fields.GetFieldByInternalName(fColl[j].StaticName);

                                if (!field.ReadOnlyField)
                                    item[fColl[j].StaticName] = properties.ListItem[fColl[j].StaticName];

                            }

                            targetList.ParentWeb.AllowUnsafeUpdates = true;
                            item.Update();
                            if (targetList.ForceCheckout)
                            {

                                if (item.File.CheckOutType != SPFile.SPCheckOutType.None)
                                    item.File.CheckIn("Inline.ExtendedVariations");

                            }
                            targetList.ParentWeb.AllowUnsafeUpdates = false;

                        }

                    }

                }

            }

        }

        public void DeleteItem(StringCollection variationUrls, SPItemEventProperties properties)
        {

            for (int i = 0; i < variationUrls.Count; i++)
            {

                using (SPSite site = new SPSite(variationUrls[i]))
                {

                    using (SPWeb web = site.OpenWeb())
                    {

                        SPList targetList = web.Lists.TryGetList(properties.ListTitle);

                        if (targetList != null) // If the list cannot be found, the item cannot be deleted
                        {

                            // If the item is not a document, we use the title as a key. Else the filename.
                            string key = string.Empty, keyColumn = string.Empty, type = string.Empty;
                            if (properties.ListItem.File == null)
                            {

                                keyColumn = "Title";
                                type = "Text";
                                key = properties.ListItem.Title;

                            }
                            else
                            {

                                keyColumn = "FileLeafRef";
                                type = "File";
                                key = properties.ListItem.File.Name;

                            }

                            // Find item based on key
                            SPQuery query = new SPQuery();
                            query.Query = "<Where><Eq><FieldRef Name=\"" + keyColumn +
                                            "\" /><Value Type=\"" + type + "\">" + key +
                                            "</Value></Eq></Where>";

                            SPListItemCollection iColl = targetList.GetItems(query);
                            if (iColl.Count == 1) // Can max be one or else we don't know which one to delete
                            {

                                SPListItem item = iColl[0];

                                targetList.ParentWeb.AllowUnsafeUpdates = true;
                                item.Delete();
                                targetList.ParentWeb.AllowUnsafeUpdates = false;

                            }

                        }

                    }

                }

            }

        }

        /// <summary>
        /// Tries to get a list item based on the given information
        /// </summary>
        /// <param name="list">The list to find the item in</param>
        /// <param name="column">The column to search on</param>
        /// <param name="columnType">The type of that column</param>
        /// <param name="value">The value it should have</param>
        /// <returns>The item if it's the only one that was found, else null</returns>
        private SPListItem GetListItemViaCamlQuery(SPList list, string column, string columnType, string value)
        {

            SPQuery query = new SPQuery();
            query.Query = "<Where><Eq><FieldRef Name=\"" + column +
                            "\" /><Value Type=\"" + columnType + "\">" + value +
                            "</Value></Eq></Where>";

            SPListItemCollection iColl = list.GetItems(query);
            if (iColl.Count == 1)
                return iColl[0];

            return null;

        }

    }

}